#ifndef SC_ACK_SYNC_H
#define SC_ACK_SYNC_H

#include "common.h"

#include "thread.h"

#define SC_SEQUENCE_INVALID 0

/**
 * Helper to wait for acknowledgments（设备消息回执）
 *  * AOA协议是Android设备与Android配件之间进行USB通信需遵循的连接协议,
 * 该协议规定了Android配件如何检测Android设备并与其建立通信。

 * In practice, it is used to wait for device clipboard acknowledgement from the
 * server before injecting Ctrl+v via AOA HID, in order to avoid pasting the
 * content of the old device clipboard (if Ctrl+v was injected before the
 * clipboard content was actually set).
 */
struct sc_acksync {
    sc_mutex mutex;
    sc_cond cond;

    bool stopped;

    // Last acked value, initially SC_SEQUENCE_INVALID
    uint64_t ack;
};

// 消息回执等待结果
enum sc_acksync_wait_result {
    // Acknowledgment received 确认收到
    SC_ACKSYNC_WAIT_OK,

    // Timeout expired 超时
    SC_ACKSYNC_WAIT_TIMEOUT,

    // Interrupted from another thread by sc_acksync_interrupt()
    SC_ACKSYNC_WAIT_INTR,
};

/* 
初始化自定义消息回执器 
@param as 
@return 
*/
bool
sc_acksync_init(struct sc_acksync *as);

/* 
销毁并清理自定义消息回执器
@param as 消息回执上下文
*/
void
sc_acksync_destroy(struct sc_acksync *as);

/**
 * Acknowledge `sequence`
 *
 * The `sequence` must be greater than (or equal to) any previous acknowledged
 * sequence.
 */
void
sc_acksync_ack(struct sc_acksync *as, uint64_t sequence);

/**
 * Wait for acknowledgment of sequence `ack` (or higher)
 */
enum sc_acksync_wait_result
sc_acksync_wait(struct sc_acksync *as, uint64_t ack, sc_tick deadline);

/**
 * Interrupt any `sc_acksync_wait()`
 */
void
sc_acksync_interrupt(struct sc_acksync *as);

#endif
